﻿#include "FITKMeshFeatureVTK.h"

// VTK
#include <vtkPolyData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>

// 过滤器
#include "FITK_Interface/FITKVTKAlgorithm/FITKSurfaceFilter.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKShellFeatureEdges.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKPolyDataNormals.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKHighOrderCellFilter.h"

namespace Interface
{
    FITKMeshFeatureVTK::FITKMeshFeatureVTK(vtkDataSet* dataSet)
    {
        // 设置模型数据。
        this->reset(dataSet);

        // 初始化。
        //@{
        // 提取表面数据过滤器。
        _surfaceFilter = FITKSurfaceFilter::New();
        // _surfaceFilter->SetInputData(_dataSet);

        // 保存单元与原数据拓扑对应关系必须设置为true。
        _surfaceFilter->SetPassThroughPointIds(true);

        // 处理高阶单元数据时必须设置为true。
        _surfaceFilter->SetPassThroughCellIds(true);

        // 高阶单元划分级为0才能正常显示。
        _surfaceFilter->SetNonlinearSubdivisionLevel(0);

        // 法向提取过滤器。
        _normalFilter = FITKPolyDataNormals::New();
        _normalFilter->SetInputConnection(_surfaceFilter->GetOutputPort());
        _normalFilter->SetComputeCellNormals(true);
        _normalFilter->SetComputePointNormals(false);

        // 特征边提取过滤器。
        _featureEdgeFilter = FITKShellFeatureEdges::New();
        _featureEdgeFilter->SetInputConnection(_surfaceFilter->GetOutputPort());
        _featureEdgeFilter->BoundaryEdgesOn();
        _featureEdgeFilter->FeatureEdgesOn();

        // 处理高阶单元过滤器。
        _highOrderFilter = FITKHighOrderCellFilter::New();

        // 需要用到提取表面时生成的原始单元id数据，
        // 默认array名称为表面提取生成的默认名称vtkOriginalCellIds。
        _highOrderFilter->SetInputConnection(_surfaceFilter->GetOutputPort());
        //@}
    }

    FITKMeshFeatureVTK::~FITKMeshFeatureVTK()
    {
        // 手动删除所有过滤器。
        //@{
        if (_highOrderFilter)
        {
            _highOrderFilter->Delete();
            _highOrderFilter = nullptr;
        }

        if (_normalFilter)
        {
            _normalFilter->Delete();
            _normalFilter = nullptr;
        }

        if (_featureEdgeFilter)
        {
            _featureEdgeFilter->Delete();
            _featureEdgeFilter = nullptr;
        }

        if (_surfaceFilter)
        {
            _surfaceFilter->Delete();
            _surfaceFilter = nullptr;
        }
        //@}
    }

    void FITKMeshFeatureVTK::update()
    {        
        // 更新数据，提取表面用来提取法向与特征边等。
        //@{
        _surfaceFilter->SetInputData(_dataSet);
        _surfaceFilter->Update();
        //@}

        // 更新法线、特征边。
        //@{
        _normalFilter->Update();
        _featureEdgeFilter->Update();
        //@}|

        // 处理高阶单元，此处生成的为实际可视化的表面数据。
        //@{
        _highOrderFilter->Update();
        //@}

        _dataSet->Modified();
    }

    void FITKMeshFeatureVTK::reset(vtkDataSet* dataSet)
    {
        _dataSet = dataSet;
    }

    FITKSurfaceFilter* FITKMeshFeatureVTK::getSurfaceFilter()
    {
        return _surfaceFilter;
    }

    FITKShellFeatureEdges* FITKMeshFeatureVTK::getFeatureEdgeFilter()
    {
        return _featureEdgeFilter;
    }

    FITKHighOrderCellFilter* FITKMeshFeatureVTK::getHighOrderFilter()
    {
        return _highOrderFilter;
    }

    FITKPolyDataNormals* FITKMeshFeatureVTK::getNormalsFilter()
    {
        return _normalFilter;
    }

    vtkPolyData* FITKMeshFeatureVTK::getFeatureMesh(int type)
    {
        // 1 - 表面 2 - 法向 3 - 特征边
        switch (type)
        {
        case 1: return _highOrderFilter->GetOutput();
        case 2: return _normalFilter->GetOutput();
        case 3: return _featureEdgeFilter->GetOutput();
        default: return nullptr;
        }

        return nullptr;
    }

    vtkDataArray* FITKMeshFeatureVTK::getCellNormals()
    {
        vtkPolyData* normalMesh = getFeatureMesh(2);
        if (!normalMesh)
        {
            return nullptr;
        }
            
        vtkCellData* cellData = normalMesh->GetCellData();
        if (!cellData)
        {
            return nullptr;
        }

        return cellData->GetNormals();
    }
}



